package com.snowflake.ecatalog.web.admin;

import java.util.List;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.validation.Valid;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springside.modules.utils.Collections3;
import org.springside.modules.web.Servlets;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.snowflake.ecatalog.entity.Company;
import com.snowflake.ecatalog.entity.CompanyCategory;
import com.snowflake.ecatalog.entity.CompanyCategoryStandard;
import com.snowflake.ecatalog.entity.CompanyLinkman;
import com.snowflake.ecatalog.service.admin.CompanyCategoryService;
import com.snowflake.ecatalog.service.admin.CompanyCategoryStandardService;
import com.snowflake.ecatalog.service.admin.CompanyService;

/**
 * Company管理的Controller, 使用Restful风格的Urls:
 * 
 * List page : GET /company/ Create page : GET /company/create Create action :
 * POST /company/create Update page : GET /company/update/{id} Update action :
 * POST /company/update Delete action : GET /company/delete/{id}
 * 
 */
@Controller
@RequestMapping(value = "/company")
public class CompanyController {

	private static final int PAGE_SIZE = 10;

	@Autowired
	private CompanyCategoryStandardService companyCategoryStandardService;
	@Autowired
	private CompanyCategoryService companyCategoryService;
	@Autowired
	private CompanyService companyService;

	@RequestMapping(value = "")
	public String list(@RequestParam(value = "standard", defaultValue = "-1") long standardId,
			@RequestParam(value = "cotegory", defaultValue = "-1") long cotegoryId,
			@RequestParam(value = "page", defaultValue = "1") int pageNumber, Model model, ServletRequest request) {
		Map<String, Object> searchParams = Servlets.getParametersStartingWith(request, "search_");
		Map<Long, String> standards = getStandardSelect();
		if (standardId < 0) {
			standardId = Long.valueOf(standards.keySet().iterator().next());
		}
		Map<Long, String> categorys = getCategorySelect(standardId);
		if (cotegoryId < 0 && categorys.size() != 0) {
			cotegoryId = Long.valueOf(categorys.keySet().iterator().next());
		}

		Page<Company> companys = companyService.getCompanys(cotegoryId, searchParams, pageNumber, PAGE_SIZE);
		model.addAttribute("companys", companys);
		model.addAttribute("searchParams", Servlets.encodeParameterStringWithPrefix(searchParams, "search_"));
		model.addAttribute("standard", standardId);
		model.addAttribute("standards", standards);
		model.addAttribute("category", cotegoryId);
		model.addAttribute("categorys", categorys);
		return "admin/companyList";
	}

	private Map<Long, String> getStandardSelect() {
		List<CompanyCategoryStandard> standards = companyCategoryStandardService
				.getEnabledCompanyCategoryStandard(null);
		Map<Long, String> select = Maps.newLinkedHashMap();
		for (CompanyCategoryStandard s : standards) {
			select.put(s.getId(), s.getName());
		}
		return select;
	}

	private Map<Long, String> getCategorySelect(Long standardId) {
		List<CompanyCategory> categorys = companyCategoryService.getEnabledCompanyCategoryByStd(standardId);
		Map<Long, String> select = Maps.newLinkedHashMap();
		for (CompanyCategory c : categorys) {
			select.put(c.getId(), c.getName());
		}
		return select;
	}

	@RequestMapping(value = "getEnabledCompanyByCategory/{categoryId}", method = RequestMethod.POST)
	public @ResponseBody
	Map<?, ?> getEnabledCompanyByCategory(@PathVariable(value = "categoryId") Long categoryId,
			@RequestParam(value = "exludeIdList[]", required = false) List<Long> exludeIdList) {
		Map<?, ?> companyMap = Maps.newHashMap();
		// 以客户Id为key，客户名称为value
		List<Company> companyList = companyService.getEnabledCompanyByCategory(categoryId, exludeIdList);
		if (CollectionUtils.isNotEmpty(companyList)) {
			companyMap = Collections3.extractToMap(companyList, "id", "name");
		}

		return companyMap;
	}

	@RequestMapping(value = "getEnabledCompanyCategoryByStd/{stdId}", method = RequestMethod.GET)
	public @ResponseBody
	Map<?, ?> getEnabledCompanyCategoryByStd(@PathVariable("stdId") Long stdId) {
		Map<?, ?> companyCategoryMap = Maps.newHashMap();
		List<CompanyCategory> companyCategoryList = companyCategoryService.getEnabledCompanyCategoryByStd(stdId);
		if (CollectionUtils.isNotEmpty(companyCategoryList)) {
			companyCategoryMap = Collections3.extractToMap(companyCategoryList, "id", "name");
		}

		return companyCategoryMap;
	}

	@RequestMapping(value = "getEnabledCompanyCategoryStandard", method = RequestMethod.POST)
	public @ResponseBody
	Map<?, ?> getEnabledCompanyCategoryStandard(
			@RequestParam(value = "exludeIdList[]", required = false) List<Long> exludeIdList) {
		Map<?, ?> companyCategoryStandardMap = Maps.newHashMap();
		// 以分类标准Id为key，分类标准名称为value
		List<CompanyCategoryStandard> companyCategoryStandardList = companyCategoryStandardService
				.getEnabledCompanyCategoryStandard(exludeIdList);
		if (CollectionUtils.isNotEmpty(companyCategoryStandardList)) {
			companyCategoryStandardMap = Collections3.extractToMap(companyCategoryStandardList, "id", "name");
		}

		return companyCategoryStandardMap;
	}

	@RequestMapping(value = "create", method = RequestMethod.GET)
	public String createForm(Model model) {
		Company newCompany = new Company();
		List<CompanyLinkman> companyLinkmans = Lists.newArrayList();
		companyLinkmans.add(new CompanyLinkman());
		newCompany.setCompanyLinkmans(companyLinkmans);
		model.addAttribute("company", newCompany);
		model.addAttribute("action", "create");
		return "admin/companyForm";
	}

	@RequestMapping(value = "create", method = RequestMethod.POST)
	public String create(@Valid Company newCompany, RedirectAttributes redirectAttributes, ServletRequest request) {
		companyService.saveCompany(newCompany);
		redirectAttributes.addFlashAttribute("message", "创建客户档案成功");
		return "redirect:/company/";
	}

	@RequestMapping(value = "update/{id}", method = RequestMethod.GET)
	public String updateForm(@PathVariable("id") Long id, Model model) {
		model.addAttribute("company", companyService.getCompany(id));
		model.addAttribute("action", "update");
		return "admin/companyForm";
	}

	@RequestMapping(value = "update", method = RequestMethod.POST)
	public String update(@Valid @ModelAttribute("preloadCompany") Company company,
			RedirectAttributes redirectAttributes, ServletRequest request) {
		companyService.updateCompany(company);
		redirectAttributes.addFlashAttribute("message", "更新客户档案成功");
		return "redirect:/company/";
	}

	@RequestMapping(value = "enable/{id}")
	public String enable(@PathVariable("id") Long id, RedirectAttributes redirectAttributes) {
		companyService.enableCompany(id);
		redirectAttributes.addFlashAttribute("message", "启用客户档案成功");
		return "redirect:/company/";
	}

	@RequestMapping(value = "disable/{id}")
	public String disable(@PathVariable("id") Long id, RedirectAttributes redirectAttributes) {
		companyService.disableCompany(id);
		redirectAttributes.addFlashAttribute("message", "禁用客户档案成功");
		return "redirect:/company/";
	}

	@RequestMapping(value = "delete/{id}")
	public String delete(@PathVariable("id") Long id, RedirectAttributes redirectAttributes) {
		if (isCompanyLinkedProfiled(id)) {
			redirectAttributes.addFlashAttribute("message", "该客户档案已关联彩页，不能删除");
		} else {
			companyService.deleteCompany(id);
			redirectAttributes.addFlashAttribute("message", "删除客户档案成功");
		}
		return "redirect:/company/";
	}

	/**
	 * 使用@ModelAttribute, 实现Struts2
	 * Preparable二次部分绑定的效果,先根据form的id从数据库查出Company对象 ,再把Form提交的内容绑定到该对象上。
	 * 因为仅update()方法的form中有id属性，因此本方法在该方法中执行.
	 */
	@ModelAttribute("preloadCompany")
	public Company getCompany(@RequestParam(value = "id", required = false) Long id) {
		if (id != null) {
			Company company = companyService.getCompany(id);
			company.setCompanyCategorys(null);
			return company;
		}
		return null;
	}

	private boolean isCompanyLinkedProfiled(Long companyId) {
		return companyService.isCompanyLinkedProfiled(companyId);
	}
}
